using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.IO;
using System.Web.SessionState;
using NetWing.Model;
using NetWing.Bll;
using Omu.ValueInjecter;
using NetWing.BPM.Core;
using NetWing.BPM.Core.Bll;
using NetWing.Common;
using NetWing.Common.Data;
using NetWing.Common.Data.SqlServer;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using NetWing.Common.Excel;
using NetWing.Common.IO;
using NetWing.Common.IO.DirFile;
using Newtonsoft.Json.Linq;
using System.Data.Linq;

namespace NetWing.BPM.Admin.FlowInstance.ashx
{
    /// <summary>
    /// 工作流实例 的摘要说明
    /// </summary>
    public class FlowInstanceHandler : IHttpHandler, IRequiresSessionState
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";

            int k;
            var json = HttpContext.Current.Request["json"];
            var rpm = new RequestParamModel<FlowInstanceModel>(context) { CurrentContext = context };
            if (!string.IsNullOrEmpty(json))
            {
                rpm = JSONhelper.ConvertToObject<RequestParamModel<FlowInstanceModel>>(json);
                rpm.CurrentContext = context;
            }
            if (string.IsNullOrEmpty(rpm.Action))
            {
                rpm.Action = context.Request["action"];
            }

            switch (rpm.Action)
            {

                case "mobileViewFlowDit"://查看流程明细
                    string ditid = context.Request["keyid"];//子订单ID
                    string vsql = "select top 1 * from FlowInstance where code like '%" + ditid + "'";
                    SqlDataReader vdr = SqlEasy.ExecuteDataReader(vsql);
                    FlowInstanceModel fimm = new FlowInstanceModel();
                    while (vdr.Read())
                    {
                        fimm.InjectFrom<ReaderInjection>(vdr);
                    }
                    string fohsql = "select * from FlowInstanceOperationHistory where InstanceId=" + fimm.KeyId + " order by keyid asc";
                    DataTable fhodt = SqlEasy.ExecuteDataTable(fohsql);
                    context.Response.Write(JSONhelper.ToJson(fhodt));


                    break;
                    
                case "mobileViewFlow"://手机查看工作流
                    string did = context.Request["keyid"];//子订单ID
                    string sql = "select top 1 * from FlowInstance where code like '%" + did + "'";
                    SqlDataReader dr = SqlEasy.ExecuteDataReader(sql);
                    FlowInstanceModel fim = new FlowInstanceModel();
                    while (dr.Read())
                    {
                        fim.InjectFrom<ReaderInjection>(dr);
                    }
                    context.Response.Write(JSONhelper.ToJson(fim));
                    break;

                case "doflow"://执行流程
                    VerificationReq vreq = new VerificationReq();
                    vreq.FlowInstanceId = context.Request["FlowInstanceId"];
                    vreq.VerificationFinally = context.Request["VerificationFinally"];
                    vreq.VerificationOpinion = context.Request["VerificationOpinion"];
                    NetWing.Model.flow.Verification(vreq);
                    context.Response.Write("1");
                    break;
                case "flow":
                    string type = context.Request["type"];
                    DataContext db = new DataContext(SqlEasy.connString);                    Table<FlowInstanceModel> fi = db.GetTable<FlowInstanceModel>();
                    Table<FlowInstanceOperationHistoryModel> fo = db.GetTable<FlowInstanceOperationHistoryModel>();
                    int t = 0;
                    IQueryable list = null;
                    switch (type)
                    {
                        case "my"://创建人是我
                            t = fi.Count(u => u.CreateUserId == int.Parse(SysVisitor.Instance.cookiesUserId));
                            list = from u in fi
                                   where u.CreateUserId == int.Parse(SysVisitor.Instance.cookiesUserId)
                                   orderby u.KeyId descending
                                   select u;
                            break;
                            
                        case "wait"://执行人等于1或者执行人是我
                            t = fi.Count(u => u.MakerList == "1" || u.MakerList.Contains(SysVisitor.Instance.cookiesUserId));
                            list = from u in fi
                                   where (u.MakerList == "1" || u.MakerList.Contains(SysVisitor.Instance.cookiesUserId))&& u.ActivityType==2
                                   orderby u.KeyId descending
                                   select u;
                            break;



                        case "disposed": //未完成
                            var instances = (from u in fo
                                             where u.CreateUserId == int.Parse(SysVisitor.Instance.cookiesUserId)
                                             select u.InstanceId).Distinct();
                            var query = from ti in instances
                                        join ct in fi on ti equals ct.KeyId
                                        into tmp
                                        from ct in tmp.DefaultIfEmpty()
                                        where ct.ActivityType!=4//等于4说明已完成
                                        orderby ct.KeyId descending
                                        select ct;
                            list = query.OrderByDescending(u => u.CreateDate);//还差分页语句
                            t = query.Count();
                            break;
                        case "finish"://已完成(用在手机和电脑）



                            var instancesfin = (from u in fo
                                                where u.CreateUserId == int.Parse(SysVisitor.Instance.cookiesUserId)
                                                select u.InstanceId).Distinct();
                            var queryfin = from ti in instancesfin
                                           join ct in fi on ti equals ct.KeyId
                                           into tmp
                                           from ct in tmp.DefaultIfEmpty()
                                           where ct.ActivityType == 4
                                           orderby ct.KeyId descending
                                           select ct;
                            list = queryfin.OrderByDescending(u => u.CreateDate);//还差分页语句
                            t = queryfin.Count();
                            break;

                        default:
                            t = fi.Count();//统计总条数
                            list = from u in fi
                                   orderby u.KeyId descending
                                   select u;
                            break;
                    }

                    context.Response.Write(JSONhelper.ToJson((new { total = t, rows = list })));//返回EasyUI格式
                    db.Dispose();
                    break;

                case "add"://添加工作流实例统一入口
                           //将json转换为JObject
                    JObject jo = JObject.Parse(json);
                    string je = jo["jsonEntity"].ToString();//取出json实体
                    JObject newjo = JObject.Parse(je);
                    bool r = NetWing.Model.flow.CreateInstance(newjo);
                    if (r)
                    {


                        context.Response.Write("1");
                    }
                    //context.Response.Write(FlowInstanceBll.Instance.Add(rpm.Entity));
                    break;
                case "edit":
                    FlowInstanceModel d = new FlowInstanceModel();
                    d.InjectFrom(rpm.Entity);
                    d.KeyId = rpm.KeyId;
                    context.Response.Write(FlowInstanceBll.Instance.Update(d));
                    break;
                case "export":
                    //string fields = rpm.fields;
                    string fields = rpm.CurrentContext.Request["fields"];
                    string tablename = TableConvention.Resolve(typeof(FlowInstanceModel));//得到表名
                    DataTable xlsDt = SqlEasy.ExecuteDataTable("select " + fields + " from " + tablename + "");
                    ExcelHelper.NPIOtoExcel(xlsDt, HttpContext.Current.Server.MapPath("\\upload\\excel\\" + tablename + ".xls"));
                    context.Response.Write("{\"status\":\"ok\",\"filename\":\"" + tablename + ".xls\"}");
                    break;
                case "inport"://从Excel导入到数据库
                    if (context.Request["REQUEST_METHOD"] == "OPTIONS")
                    {
                        context.Response.End();
                    }
                    SaveFile("~/temp/", context);
                    break;
                case "delete":
                    context.Response.Write(FlowInstanceBll.Instance.Delete(rpm.KeyId));
                    break;
                case "alldel"://2017-04-05新增的功能 批量删除删除结果返回删除条数
                    context.Response.Write(NetWing.Dal.FlowInstanceDal.Instance.Delete(rpm.KeyIds));
                    break;
                default:

                    string sqlwhere = " 1=1 ";

                    if (!string.IsNullOrEmpty(rpm.Filter))//如果筛选不为空
                    {
                        string str = " and " + NetWing.Common.Data.Filter.FilterTranslator.ToSql(rpm.Filter);
                        sqlwhere = sqlwhere + str;
                    }

                    string sort = rpm.Sort;
                    if (sort == null)
                    {
                        sort = "keyid desc";
                    }
                    
                    //TableConvention.Resolve(typeof(MJUserModel)) 转换成表名
                    var pcp = new ProcCustomPage(TableConvention.Resolve(typeof(FlowInstanceModel)))
                    {
                        PageIndex = rpm.Pageindex,
                        PageSize = rpm.Pagesize,
                        OrderFields = sort,
                        WhereString = sqlwhere,
                        
                    };
                    int recordCount;
                    DataTable dt = DbUtils.GetPageWithSp(pcp, out recordCount);
                    context.Response.Write(JSONhelper.FormatJSONForEasyuiDataGrid(recordCount, dt));

                    //context.Response.Write(FlowInstanceBll.Instance.GetJson(rpm.Pageindex, rpm.Pagesize, rpm.Filter, rpm.Sort, rpm.Order));
                    break;
            }
        }

        /// <summary>
        /// 文件保存操作
        /// </summary>
        /// <param name="basePath"></param>
        private void SaveFile(string basePath, HttpContext context)
        {
            var name = string.Empty;
            basePath = (basePath.IndexOf("~") > -1) ? context.Server.MapPath(basePath) :
            basePath;
            HttpFileCollection files = context.Request.Files;

            if (!Directory.Exists(basePath))//如果文件夹不存在创建文件夹
                Directory.CreateDirectory(basePath);
            //清空temp文件夹
            DirFileHelper.ClearDirectory(basePath);

            var suffix = files[0].ContentType.Split('/');
            var _suffix = suffix[1].Equals("jpeg", StringComparison.CurrentCultureIgnoreCase) ? "" : suffix[1];
            var _temp = System.Web.HttpContext.Current.Request["name"];

            if (!string.IsNullOrEmpty(_temp))
            {
                name = _temp;
            }
            else
            {
                Random rand = new Random(24 * (int)DateTime.Now.Ticks);
                name = rand.Next() + "." + _suffix;
            }

            var full = basePath + name;
            files[0].SaveAs(full);

            DataTable dt = NPOIHelper.ImportExceltoDt(full);
            string connectionString = SqlEasy.connString;
            SqlBulkCopy sqlbulkcopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction);
            sqlbulkcopy.DestinationTableName = TableConvention.Resolve(typeof(FlowInstanceModel));//数据库中的表名
                                                                                                  //自定义的datatable和数据库的字段进行对应  
                                                                                                  //sqlBC.ColumnMappings.Add("id", "tel");  
                                                                                                  //sqlBC.ColumnMappings.Add("name", "neirong");  
            int k = dt.Rows.Count - 1;                                                                       //注意一个问题，最后一列是字段数
            for (int i = 0; i < (dt.Columns.Count - 1); i++)
            {
                sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName.ToString(), dt.Columns[i].ColumnName.ToString());

            }
            var _result = "";
            try
            {
                sqlbulkcopy.WriteToServer(dt);
                _result = "{\"msg\" : \"导入数据库成功!\", \"result\" : " + k + ", \"filename\" : \"" + name + "\"}";
            }
            catch (Exception)
            {
                _result = "{\"msg\" : \"导入失败,可能模板不对，或其他原因，建议导出数据作为模板重新处理。注意导入没有校验数据重复功能。请人工校验数据!\", \"result\" : 0, \"filename\" : \"" + name + "\"}";
                //throw;
            }



            System.Web.HttpContext.Current.Response.Write(_result);

        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}